﻿using Microsoft.IdentityModel.Tokens;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

namespace CoreWebApiNuGet.JwtAuthentication
{
    /// <summary>
    /// HMAC算法
    /// </summary>
    public class JwtUtility
    {
        /// <summary>
        /// 组装 HmacSha256 签名证书
        /// </summary>
        /// <param name="secret"> </param>
        /// <returns> </returns>
        public static SigningCredentials BuildHmacSha256Credentials(string secret)
        {
            var keyByteArray = Encoding.ASCII.GetBytes(secret);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            return new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
        }

        /// <summary>
        /// 生成随机字符串
        /// </summary>
        /// <param name="length"> 目标字符串的长度 </param>
        /// <param name="useNum"> 是否包含数字，1=包含，默认为包含 </param>
        /// <param name="useLow"> 是否包含小写字母，1=包含，默认为包含 </param>
        /// <param name="useUpp"> 是否包含大写字母，1=包含，默认为包含 </param>
        /// <param name="useSpe"> 是否包含特殊字符，1=包含，默认为不包含 </param>
        /// <param name="custom"> 要包含的自定义字符，直接输入要包含的字符列表 </param>
        /// <returns> 指定长度的随机字符串 </returns>
        public static string GetRandomString(int length, bool useNum, bool useLow, bool useUpp, bool useSpe, string custom = null)
        {
            var b = new byte[4];
            new RNGCryptoServiceProvider().GetBytes(b);
            var r = new System.Random(BitConverter.ToInt32(b, 0));
            string Random = null;
            if (useNum) custom += "0123456789";
            if (useLow) custom += "abcdefghijklmnopqrstuvwxyz";
            if (useUpp) custom += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            if (useSpe) custom += "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
            for (var i = 0; i < length; i++) Random += custom.Substring(r.Next(0, custom.Length - 1), 1);
            return Random;
        }

        /// <summary>
        /// 实体转键值对
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Dictionary<string, string> EntityToDictionary<T>(T obj) where T : class
        {
            //初始化定义一个键值对，注意最后的括号
            Dictionary<string, string> dic = new Dictionary<string, string>();
            //返回当前 Type 的所有公共属性Property集合
            PropertyInfo[] props = typeof(T).GetProperties();
            foreach (PropertyInfo p in props)
            {
                var value = p.GetValue(obj);//获取属性值
                dic.Add(p.Name, value == null ? "null" : value.ToString());
            }
            return dic;
        }
    }
}
